package com.dly.hope.excelhandle;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.dly.hope.constant.ExceptionConstant;
import com.dly.hope.constant.GlobalException;
import com.dly.hope.utils.ExceptionPropertiesUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author DBC20220821
 */
@Slf4j
@Component
@Data
public class EasyExcelLister<T> extends AnalysisEventListener<T> {

    private List<T> saveDataLists = Lists.newArrayList();

    private Class<T> cla;

    private List<String> headerErrorMsg  = Lists.newArrayList();

    public EasyExcelLister() {
    }

    public EasyExcelLister(Class<T> cla) {
        this.cla = cla;
    }

    /**
     * 每解析到一条数据都会来调用这个
     * @param data    one row value. Is is same as {@link AnalysisContext#readRowHolder()}
     * @param context analysis context
     */
    @Override
    public void invoke(T data, AnalysisContext context) {
        saveDataLists.add(data);
    }

    /**
     * 所有数据解析完成了 都会来调用
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        log.info("doAfterAllAnalysed");
    }

    /**
     * @Author linyu.dai
     * @Description 对比解析出来的模板头
     * @Date 2022/11/16 14:02
     * @Param [headMap, context]
     * @return void
     */
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        List<String> nameMap = getNameMap();
        nameMap.forEach(m->{
            if (!headMap.containsValue(m)){
                headerErrorMsg.add(m);
            }
        });
        if (CollectionUtils.isNotEmpty(headerErrorMsg)){
            throw new ExcelAnalysisException(ExceptionPropertiesUtil.getMsg(ExceptionConstant.EXCEL_ERROR));
        }
    }

    /**
     * @Author linyu.dai
     * @Description 出现异常
     * @Date 2022/11/16 14:03
     * @Param [exception, context]
     * @return void
     */
    @Override
    public void onException(Exception exception, AnalysisContext context) {
        log.error(exception.getMessage());
        if (CollectionUtils.isNotEmpty(headerErrorMsg)){
            throw new GlobalException(ExceptionConstant.EXCEL_HEADER_MESSAGE,String.format(ExceptionPropertiesUtil.getMsg(ExceptionConstant.EXCEL_HEADER_MESSAGE), headerErrorMsg));
        }
    }

    /**
     * @Author linyu.dai
     * @Description 获取注解上的列名
     * @Date 2022/11/16 14:03
     * @Param []
     * @return java.util.List<java.lang.String>
     */
    public List<String> getNameMap(){
        List<String> vs = Lists.newArrayList();
        Field[] declaredFields = cla.getDeclaredFields();
        Arrays.stream(declaredFields).forEach(field -> {
            ExcelProperty annotation = field.getAnnotation(ExcelProperty.class);
            StringBuilder str = new StringBuilder();
            Arrays.stream(annotation.value()).forEach(str::append);
            vs.add(String.valueOf(str));
        });
        return vs;
    }

}
